// 增加排队播放功能
package main

import (
	"bytes"
	"fmt"
	"io"
	"net"
	"os"
	"sync"
	"time"

	"github.com/faiface/beep"
	"github.com/faiface/beep/mp3"
	"github.com/faiface/beep/speaker"
	"github.com/faiface/beep/wav"
)

const (
	TCPAddr          = "0.0.0.0:10110"
	UDPAddr          = "0.0.0.0:10111"
	END_MARKER       = "\r\n"
	MaxUDPPacketSize = 65535
)

var speakerInitialized bool
var speakerMutex sync.Mutex

// 播放队列和锁
var (
	audioQueue = make(chan []byte, 100)
)

func main() {
	go startTCPServer()
	go startUDPServer()
	go audioPlaybackWorker() // 启动播放线程
	select {}
}

// ---------------- TCP ----------------
func startTCPServer() {
	ln, err := net.Listen("tcp", TCPAddr)
	if err != nil {
		panic(fmt.Sprintf("TCP监听失败: %v", err))
	}
	defer ln.Close()
	fmt.Println("TCP监听中:", TCPAddr)

	for {
		conn, err := ln.Accept()
		if err != nil {
			fmt.Println("TCP连接失败:", err)
			continue
		}
		go handleTCPConn(conn)
	}
}

func handleTCPConn(conn net.Conn) {
	defer conn.Close()
	fmt.Println("收到TCP连接:", conn.RemoteAddr())

	var buf bytes.Buffer
	for {
		tmp := make([]byte, 1024)
		n, err := conn.Read(tmp)
		if err != nil {
			if err != io.EOF {
				fmt.Println("TCP读取失败:", err)
			}
			break
		}
		buf.Write(tmp[:n])
		if buf.Len() >= 2 && bytes.HasSuffix(buf.Bytes(), []byte(END_MARKER)) {
			break
		}
	}

	data := trimEndMarker(buf.Bytes())
	audioQueue <- data
}

// ---------------- UDP ----------------
func startUDPServer() {
	addr, err := net.ResolveUDPAddr("udp", UDPAddr)
	if err != nil {
		panic(fmt.Sprintf("UDP地址解析失败: %v", err))
	}
	conn, err := net.ListenUDP("udp", addr)
	if err != nil {
		panic(fmt.Sprintf("UDP监听失败: %v", err))
	}
	defer conn.Close()
	fmt.Println("UDP监听中:", UDPAddr)

	var (
		buffer = bytes.Buffer{}
		tmp    = make([]byte, MaxUDPPacketSize)
	)

	for {
		n, remoteAddr, err := conn.ReadFromUDP(tmp)
		if err != nil {
			fmt.Println("UDP接收失败:", err)
			continue
		}
		fmt.Printf("收到UDP数据 %d 字节 来自 %s\n", n, remoteAddr)
		buffer.Write(tmp[:n])

		if buffer.Len() >= 2 && bytes.HasSuffix(buffer.Bytes(), []byte(END_MARKER)) {
			data := trimEndMarker(buffer.Bytes())
			buffer.Reset()
			audioQueue <- data
		}
	}
}

// ---------------- 播放线程 ----------------
func audioPlaybackWorker() {
	for data := range audioQueue {
		if err := playAudio(data); err != nil {
			fmt.Println("播放失败:", err)
		}
	}
}

// ---------------- 共用 ----------------
func playAudio(data []byte) error {
	os.WriteFile("debug_audio.raw", data, 0644)

	var (
		streamer beep.StreamSeekCloser
		format   beep.Format
		err      error
	)
	reader := bytes.NewReader(data)

	if isWAV(data) {
		streamer, format, err = wav.Decode(reader)
		fmt.Println("识别为 WAV 格式")
	} else if isMP3(data) {
		streamer, format, err = mp3.Decode(NewReadCloser(reader))
		fmt.Println("识别为 MP3 格式")
	} else {
		return fmt.Errorf("不支持的音频格式")
	}
	if err != nil {
		return fmt.Errorf("解码失败: %w", err)
	}
	defer streamer.Close()

	speakerMutex.Lock()
	if !speakerInitialized {
		err = speaker.Init(format.SampleRate, format.SampleRate.N(time.Second/10))
		if err != nil {
			speakerMutex.Unlock()
			return fmt.Errorf("初始化失败: %w", err)
		}
		speakerInitialized = true
	}
	speakerMutex.Unlock()
	done := make(chan bool)
	speaker.Play(beep.Seq(streamer, beep.Callback(func() {
		done <- true
	})))
	<-done
	return nil
}

func trimEndMarker(data []byte) []byte {
	if len(data) >= 2 && string(data[len(data)-2:]) == END_MARKER {
		return data[:len(data)-2]
	}
	return data
}

func isWAV(data []byte) bool {
	return len(data) >= 12 && string(data[:4]) == "RIFF" && string(data[8:12]) == "WAVE"
}

func isMP3(data []byte) bool {
	return len(data) >= 2 && data[0] == 0xFF && (data[1]&0xE0) == 0xE0
}

type ReadCloser struct {
	*bytes.Reader
}

func (rc *ReadCloser) Close() error { return nil }

func NewReadCloser(r io.Reader) *ReadCloser {
	return &ReadCloser{Reader: r.(*bytes.Reader)}
}
